import {
  IPSDBAppViewPortletPart,
  IPSDBPortletPart,
  IPSDEUIAction,
  IPSUIActionGroupDetail,
} from '@ibiz/dynamic-model-api';
import { Util } from '../../../util';
import { AppCtrlEvents, ICtrlActionResult, IMobPortletController, IParam, IViewStateParam, MobPortletEvents, AppViewEvents } from '../../../interface';
import { AppCtrlControllerBase } from './app-ctrl-controller-base';

/**
 * 移动端门户部件控制器
 *
 * @exports
 * @class MobPortletController
 * @extends AppCtrlControllerBase
 * @implements IMobPortletController
 */
export class MobPortletController extends AppCtrlControllerBase implements IMobPortletController {
  /**
   * @description 门户部件实例对象
   * @type {IPSDBPortletPart}
   * @memberof MobPortletController
   */
  public controlInstance!: IPSDBPortletPart;

  /**
   * @description 操作栏模型数据
   * @type {IParam[]}
   * @memberof MobPortletController
   */
  public actionBarModel: IParam[] = [];

  /**
   * @description 是否视图已经完成
   * @type {boolean}
   * @memberof MobPortletController
   */
  public hasViewMounted: boolean = false;

  /**
   * @description 部件基础数据初始化
   * @memberof MobPortletController
   */
  public ctrlBasicInit() {
    super.ctrlBasicInit();
    this.initActionBarModel();
  }

  /**
   * @description 初始化界面行为模型
   * @memberof MobPortletController
   */
  public initActionBarModel() {
    //  TODO计数器
    const groupDetails = this.controlInstance.getPSUIActionGroup?.()?.getPSUIActionGroupDetails?.() || [];
    this.actionBarModel = [];
    groupDetails.forEach((detail: IPSUIActionGroupDetail) => {
      const uiAction = detail.getPSUIAction();
      if (uiAction) {
        this.actionBarModel.push({
          viewLogicName: detail.name,
          icon: uiAction.getPSSysImage?.()?.cssClass,
          name: uiAction.caption,
          language: uiAction.getCapPSLanguageRes()?.lanResTag,
          disabled: false,
          visabled: true,
          noPrivDisplayMode: (uiAction as IPSDEUIAction).noPrivDisplayMode || 6,
        });
      }
    });
  }

  /**
   * @description 部件初始化
   * @memberof MobPortletController
   */
  public ctrlInit() {
    super.ctrlInit();
    if (this.viewState) {
      this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }: IViewStateParam) => {
        if (Object.is(tag, 'all-portlet')) {
          switch (action) {
            case MobPortletEvents.LOAD_MODEL:
              this.calcUIActionAuthState(data);
              break;
            case MobPortletEvents.REFRESH_ALL:
              this.refreshAll(data);
              break;
          }
          return;
        }
        if (!Object.is(tag, this.name)) {
          return;
        }
        if (action == MobPortletEvents.LOAD) {
          this.notifyControlLoad(data);
        }
      });
    }
  }

  /**
   * @description 通知部件加载
   * @param data
   * @memberof MobPortletController
   */
  private notifyControlLoad(args: any) {
    try {
      const portletType = this.controlInstance.portletType;
      switch (portletType) {
        case 'VIEW':
          const view = (this.controlInstance as IPSDBAppViewPortletPart).getPortletPSAppView?.();
          this.viewState.next({ tag: view?.name, action: MobPortletEvents.LOAD, data: Util.deepCopy(args) });
          break;
        case 'CHART':
        case 'LIST':
          const controls = this.controlInstance.getPSControls?.();
          this.viewState.next({ tag: controls?.[0]?.name, action: MobPortletEvents.LOAD, data: Util.deepCopy(args) });
          break;
      }
      return { ret: true, data: args ? [args] : [] };
    } catch (error) {
      return { ret: false, data: args ? [args] : [] };
    }
  }

  /**
   *
   * @description 刷新
   * @param {IParam} args 数据
   * @param {IParam} opts 额外参数
   * @param {boolean} showInfo 是否展示结果
   * @param {boolean} isloadding 是否显示加载效果
   */
  public async refresh(
    args?: IParam,
    opts?: IParam,
    showInfo: boolean = this.showBusyIndicator,
    isloadding: boolean = true,
  ): Promise<ICtrlActionResult> {
    try {
      const portletType = this.controlInstance.portletType;
      switch (portletType) {
        case 'VIEW':
          const view = (this.controlInstance as IPSDBAppViewPortletPart).getPortletPSAppView?.();
          this.viewState.next({ tag: view?.name, action: MobPortletEvents.REFRESH, data: Util.deepCopy(args) });
          break;
        case 'CHART':
        case 'LIST':
          const controls = this.controlInstance.getPSControls?.();
          this.viewState.next({ tag: controls?.[0]?.name, action: MobPortletEvents.REFRESH, data: Util.deepCopy(args) });
          break;
        case 'ACTIONBAR':
          this.ctrlEvent(MobPortletEvents.REFRESH_ALL, Util.deepCopy(args));
          break;
      }
      return { ret: true, data: args ? [args] : [] };
    } catch (error) {
      return { ret: false, data: args ? [args] : [] };
    }
  }

  /**
   * @description 刷新全部
   * @param {*} data 数据
   */
  public refreshAll(data?: any) {
    const portletType = this.controlInstance.portletType;
    if (portletType == 'VIEW' || portletType == 'CHART' || portletType == 'LIST') {
      this.refresh(data);
    }
  }

  /**
   * @description 计算操作栏权限
   * @param data
   * @memberof MobPortletController
   */
  public calcUIActionAuthState(data: IParam = {}) {
    //  如果是操作栏，不计算权限
    if (this.controlInstance?.portletType == 'ACTIONBAR') {
      return;
    }
    // const uiService = this.appUIService ? this.appUIService : App.getUIService().getService(this.context, this.appDeCodeName.toLowerCase());
    // if (this.appUIService && this.uiActionModel) {
    //   ViewTool.calcActionItemAuthState(data, this.uiActionModel, uiService);
    // }
  }

  /**
   * @description 操作栏按钮点击
   * @param {string} tag 标识
   * @param {*} event 源事件对象
   * @memberof MobPortletController
   */
  public actionBarItemClick(tag: string, event: any) {
    this.handleActionClick(this.getData(), event, { name: tag });
  }

  /**
   * 处理视图事件
   *
   * @param {string} viewName 视图名称
   * @param {string} action 行为标识
   * @param {*} data 数据
   */
  public handleViewEvent(viewName: string, action: string, data: any) {
    const view = (this.controlInstance as IPSDBAppViewPortletPart).getPortletPSAppView?.();
    if (view && Object.is(view.name, viewName)) {
      switch (action) {
        case AppViewEvents.MOUNTED:
          this.hasViewMounted = true;
          this.ctrlMounted();
          break;
      }
    }
  }

  /**
   * @description 部件挂载
   * @param {*} [args]
   * @memberof MobPortletController
   */
  public ctrlMounted(args?: any) {
    this.hasCtrlMounted = true;
    if (Object.is('VIEW', this.controlInstance.portletType)) {
      if (this.hasViewMounted) {
        this.ctrlEvent(AppCtrlEvents.MOUNTED, this);
        this.hooks.mounted.callSync({ arg: this });
      }
    } else {
      this.ctrlEvent(AppCtrlEvents.MOUNTED, this);
      this.hooks.mounted.callSync({ arg: this });
    }
  }
}
